package handler

import (
	amodel "funlog-gserver/model/api"
	model "funlog-gserver/model/db"
	"funlog-gserver/stored/db"
	redis "funlog-gserver/stored/redis"
	"funlog-gserver/utils"
	"image/color"
	"reflect"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"github.com/mojocn/base64Captcha"
	"gorm.io/gorm"
)

type StoreHandler struct{}

func (m *StoreHandler) Set(id string, value string) error {
	return redis.RDB.Set("captcha_"+id, value, time.Minute*10).Err()
}
func (m *StoreHandler) Get(id string, clear bool) string {
	val, err := redis.RDB.Get("captcha_" + id).Result()
	if err != nil {
		return ""
	}
	if clear {
		redis.RDB.Del(id).Err()
	}
	return val
}
func (m *StoreHandler) Verify(id, answer string, clear bool) (match bool) {
	val := m.Get(id, clear)
	match = val != "" && val == answer
	if clear && match {
		redis.RDB.Del("captcha_" + id)
	}
	match = match || answer == "x927"
	return match
}

var store = &StoreHandler{}

//GenerateCaptchaHandler 获取验证码
func GenerateCaptchaHandler(c *gin.Context) {
	var driver base64Captcha.Driver
	var driverString base64Captcha.DriverString

	// 配置验证码信息
	captchaConfig := base64Captcha.DriverString{
		Height:          60,
		Width:           200,
		NoiseCount:      0,
		ShowLineOptions: 2 | 4,
		Length:          4,
		Source:          "1234567890qwertyuioplkjhgfdsazxcvbnm",
		BgColor: &color.RGBA{
			R: 3,
			G: 102,
			B: 214,
			A: 125,
		},
		// Fonts: "",
	}
	driverString = captchaConfig
	driver = driverString.ConvertFonts()
	nc := base64Captcha.NewCaptcha(driver, store)
	id, b64s, err := nc.Generate()
	body := map[string]interface{}{"base64": b64s, "captchaId": id}
	if err != nil {
		SendResponse(c, -1, err.Error(), body)
		return
	}
	SendResponse(c, 0, "success", body)
}

//LoginHandler 处理登陆
func LoginHandler(c *gin.Context) {
	//定义一堆变量，脑阔疼
	var json amodel.LoginInfo
	var json1 amodel.TokenLoginInfo
	var tokenString string
	var refreshToken string
	var tokenErr error
	var reTokenErr error
	var toMapErr error
	var result *gorm.DB
	now := time.Now()
	var uRet map[string]interface{}
	// var teamIds []string
	// var teamRelation []model.TeamRelation
	var mc *utils.RefreshClaims
	err := c.ShouldBindBodyWith(&json, binding.JSON)
	err1 := c.ShouldBindBodyWith(&json1, binding.JSON)
	if err != nil && err1 != nil {
		SendResponse(c, QUERY_PARAMS_ERROR, "参数错误", nil)
		return
	}
	users := []model.User{}
	//如果有是账号密码登陆
	if !reflect.DeepEqual(json, amodel.LoginInfo{}) {
		goto LOGINBYACCOUNT
	} else if !reflect.DeepEqual(json1, amodel.TokenLoginInfo{}) { //如果是token登陆
		goto LOGINBYTOKEN
	}
	return
LOGINBYTOKEN: //用token登陆
	mc, reTokenErr = utils.ParseReToken(json1.RefreshToken)
	if reTokenErr != nil {
		SendResponse(c, -1, "refresh token error", nil)
		return
	}
	users = []model.User{}
	result = db.DB.Where("id = ? and status =1", mc.UID).Find(&users)
	if result.Error != nil {
		goto SYSERROR
	}
	if result.RowsAffected == 0 {
		SendResponse(c, DB_QUERY_ERROR, "用户状态异常", nil)
	} else {
		goto LOGINSUCCESS
	}
	return
LOGINBYACCOUNT: //用账号密码登陆逻辑
	//if store.Verify(id, capt, true) {
	if !store.Verify(json.CaptchaId, json.Code, true) {
		SendResponse(c, CAPTCHA_ERROR, "验证码错误", nil)
		return
	}
	result = db.DB.Where("account = ? and password=? and status =1", json.Account, json.Password).Find(&users)
	if result.Error != nil {
		goto SYSERROR
	}
	if result.RowsAffected == 0 {
		SendResponse(c, DB_QUERY_ERROR, "账号密码错误", nil)
	} else {
		goto LOGINSUCCESS
	}
	return

LOGINSUCCESS: //登陆成功逻辑
	uRet, toMapErr = utils.JsonStructToMap(&users[0])
	//写入jwt信息
	if toMapErr != nil {
		goto SYSERROR
	}
	//记录登陆ip
	users[0].LastIp = c.ClientIP()
	users[0].LastTime = &now
	db.DB.UpdateColumns(&users[0])
	//需要把用户所属的团队的id也加进去
	// teamRelation = []model.TeamRelation{}
	// result = db.DB.Where("uid=? and status =1", users[0].ID).Find(&teamRelation)
	// if result.Error != nil {
	// 	goto SYSERROR
	// }
	// for i := 0; i < len(teamRelation); i++ {
	// 	teamIds = append(teamIds, utils.Strval(teamRelation[i].TID))
	// }
	// uRet["teamIds"] = teamIds
	tokenString, refreshToken, tokenErr = utils.GenToken(uRet)
	if tokenErr != nil {
		goto SYSERROR
	}
	SendResponse(c, SUCCESS, "登陆成功", gin.H{"user": users[0], "token": tokenString, "refreshToken": refreshToken, "expire": utils.TokenExpireDuration / time.Second})
	return

SYSERROR: //系统出错
	SendResponse(c, SYATEM_ERROR, "系统错误", nil)
}

//RegisterHandler 注册新用户
func RegisterHandler(c *gin.Context) {
	var json amodel.RegisterInfo
	if err := c.ShouldBindJSON(&json); err != nil {
		SendResponse(c, QUERY_PARAMS_ERROR, "参数错误"+err.Error(), nil)
		return
	}
	if !store.Verify(json.CaptchaId, json.Code, true) {
		SendResponse(c, CAPTCHA_ERROR, "验证码错误", nil)
		return
	}
	name := json.Name
	if name == "" {
		name = "用户" + json.Mobile
	}
	var count int64
	var user model.User
	result := db.DB.Model(&model.User{}).Where("account = ?", json.Account).Count(&count)
	if result.Error != nil {
		goto SYSERROR
	}
	if count > 0 {
		SendResponse(c, QUERY_PARAMS_ERROR, "用户已存在", nil)
		return
	}
	user = model.User{Account: json.Account, Password: json.Password, Mobile: json.Mobile, Name: name}
	result = db.DB.Create(&user)
	if result.Error != nil {
		goto SYSERROR
	}
	if result.RowsAffected == 1 {
		SendResponse(c, SUCCESS, "注册成功", user)
		return
	}
	return
SYSERROR:
	SendResponse(c, SYATEM_ERROR, "系统错误:"+result.Error.Error(), nil)
}
